/**
 *  collision.cpp
 *  AwkwardPaint - Engine
 *
 *  Date: 11/08/2013
 *
 *  Language: C++
 *
 *  @author Carl McCaffrey
 *
 */
#include "physics/collision/collision.h"

bool CollisionManager::TestCollision(Collider* body1, Collider* body2, Vector2* normal)
{
    if(body1->type == COLLIDER_TYPE_RECT && body2->type == COLLIDER_TYPE_RECT){
        if(body1->rect.orientation == 0 && body2->rect.orientation == 0){
            return AABBCollision(body1, body2, normal);
        }else{
            return OBBCollision(body1, body2, normal);
        }
    }

    if(body1->type == COLLIDER_TYPE_CIRCLE && body2->type == COLLIDER_TYPE_CIRCLE){
        return CircleCollision(body1, body2, normal);
    }

    if(body1->type == COLLIDER_TYPE_TRIANGLE && body2->type == COLLIDER_TYPE_TRIANGLE){
        return TriangleCollision(body1, body2, normal);
    }

    if((body1->type == COLLIDER_TYPE_RECT && body2->type == COLLIDER_TYPE_CIRCLE) || (body1->type == COLLIDER_TYPE_CIRCLE && body2->type == COLLIDER_TYPE_RECT)){
        if((body1->type == COLLIDER_TYPE_RECT && body1->rect.orientation == 0) || (body2->type == COLLIDER_TYPE_RECT && body2->rect.orientation == 0)){
            if(body1->type == COLLIDER_TYPE_RECT){
                return AABBCircleCollision(body1, body2, normal);
            }else{
                return AABBCircleCollision(body2, body1, normal);
            }
        }else{
            if(body1->type == COLLIDER_TYPE_RECT){
                return OBBCircleCollision(body1, body2, normal);
            }else{
                return OBBCircleCollision(body2, body1, normal);
            }
        }
    }

    if((body1->type == COLLIDER_TYPE_RECT && body2->type == COLLIDER_TYPE_TRIANGLE) || (body1->type == COLLIDER_TYPE_TRIANGLE && body2->type == COLLIDER_TYPE_RECT)){
        if((body1->type == COLLIDER_TYPE_RECT && body1->rect.orientation == 0) || (body2->type == COLLIDER_TYPE_RECT && body2->rect.orientation == 0)){
            if(body1->type == COLLIDER_TYPE_RECT){
                return AABBTriangleCollision(body1, body2, normal);
            }else{
                return AABBTriangleCollision(body2, body1, normal);
            }
        }else{
            if(body1->type == COLLIDER_TYPE_RECT){
                return OBBTriangleCollision(body1, body2, normal);
            }else{
                return OBBTriangleCollision(body2, body1, normal);
            }
        }
    }

    if((body1->type == COLLIDER_TYPE_CIRCLE && body2->type == COLLIDER_TYPE_TRIANGLE) || (body1->type == COLLIDER_TYPE_TRIANGLE && body2->type == COLLIDER_TYPE_CIRCLE)){
        if(body1->type == COLLIDER_TYPE_CIRCLE){
            return CircleTriangleCollision(body1, body2, normal);
        }else{
            return CircleTriangleCollision(body2, body1, normal);
        }
    }

    return false;
}

bool CollisionManager::AABBCollision(Collider* body1, Collider* body2, Vector2* normal)
{
    normal->x = 0;
    normal->y = 0;

    Vector2 dist, abs_dist;

    dist.x = body1->rect.pos.x - body2->rect.pos.x;
    dist.y = body1->rect.pos.y - body2->rect.pos.y;

    float x_add = ((body1->rect.size.x * body1->rect.scale) + (body2->rect.size.x * body2->rect.scale)) / 2.0f;
    float y_add = ((body1->rect.size.y * body1->rect.scale) + (body2->rect.size.y * body2->rect.scale)) / 2.0f;

    if(dist.x < 0){
        abs_dist.x = dist.x * -1;
    }else{
        abs_dist.x = dist.x;
    }
    if(dist.y < 0){
        abs_dist.y = dist.y * -1;
    }else{
        abs_dist.y = dist.y;
    }

    if(!((abs_dist.x < x_add) && (abs_dist.y < y_add))){
        return false;
    }

    float x_mag = x_add - abs_dist.x;
    float y_mag = y_add - abs_dist.y;

    if(x_mag < y_mag){
        if(dist.x > 0){
            normal->x = x_mag;
        }else{
            normal->x = -x_mag;
        }
    }else{
        if(dist.y > 0){
            normal->y = y_mag;
        }else{
            normal->y = -y_mag;
        }
    }
    return true;
}

bool CollisionManager::OBBCollision(Collider* body1, Collider* body2, Vector2* normal)
{
    return false;
}

bool CollisionManager::CircleCollision(Collider* body1, Collider* body2, Vector2* normal)
{
    return false;
}

bool CollisionManager::TriangleCollision(Collider* body1, Collider* body2, Vector2* normal)
{
    return false;
}

bool CollisionManager::AABBCircleCollision(Collider* body1, Collider* body2, Vector2* normal)
{
    return false;
}

bool CollisionManager::OBBCircleCollision(Collider* body1, Collider* body2, Vector2* normal)
{
    return false;
}

bool CollisionManager::AABBTriangleCollision(Collider* body1, Collider* body2, Vector2* normal)
{
    return false;
}

bool CollisionManager::OBBTriangleCollision(Collider* body1, Collider* body2, Vector2* normal)
{
    return false;
}

bool CollisionManager::CircleTriangleCollision(Collider* body1, Collider* body2, Vector2* normal)
{
    return false;
}
